<template>
  <div class="fx-rate">
    <ul class="fx-rate-list" @mouseleave="rateMouseleave">
      <li v-for="(item,index) in rateList" :key="item"
          @mouseenter="rateMousemove($event,index)">
        <fx-rate-item :rate="currentValue" :index="index"
                      :step="step" :color="colorList" :readonly="readonly"
                      @change="rateItemClick($event,index)">
          <span v-if="text">{{ item }}</span>
          <slot v-else><span><i class="iconfont icon-star fs16"/></span></slot>
        </fx-rate-item>
      </li>
    </ul>
  </div>
</template>

<script lang="ts">
import { computed, defineComponent, PropType, ref } from 'vue'
import { useModelWatch } from '@/base/hooks'
import rateItem from '@/base/rate/rateItem.vue'

interface RateProps {
  modelValue: number;
  text: string | string[];
  step: number;
  color: string | string[];
  readonly: boolean;
}

export default defineComponent({
  name: 'FRate',
  components: {
    [rateItem.name]: rateItem
  },
  props: {
    modelValue: {
      type: Number as PropType<number>,
      default: 0
    },
    text: {
      type: [String, Array] as PropType<string | string[]>,
      default: ''
    },
    step: {
      type: Number as PropType<number>,
      default: 1
    },
    color: {
      type: [String, Array] as PropType<string | string[]>,
      default: '#f7ba2a'
    },
    readonly: {
      type: Boolean as PropType<boolean>,
      default: false
    }
  },
  setup (props: RateProps) {
    const currentValue = ref<number>(props.modelValue)
    const oldValue = ref<number>(props.modelValue)
    useModelWatch(() => props.modelValue, currentValue)

    const rateMousemove = (ev: MouseEvent, index: number): void => {
      if (props.readonly) return
      currentValue.value = index
    }

    const rateMouseleave = (): void => {
      if (props.readonly) return
      currentValue.value = oldValue.value
    }

    const rateList = computed(() => {
      if (props.text instanceof Array) {
        return props.text
      } else if (typeof props.text === 'string') {
        return new Array(5).fill(props.text)
      } else {
        return new Array(5)
      }
    })

    const colorList = computed((): string => {
      const { color } = props
      if (color instanceof Array) {
        const index = Math.floor(currentValue.value) - 1
        return color[index] || color[color.length - 1]
      } else {
        return color
      }
    })

    const rateItemClick = (rate: { value: number, type: 'mousemove' | 'click' }, index: number): void => {
      if (props.readonly) return
      if (rate.type === 'click') {
        oldValue.value = rate.value + index
      } else if (rate.type === 'mousemove') {
        currentValue.value = rate.value + index
      }
    }

    return {
      rateList,
      currentValue,
      colorList,
      rateItemClick,
      rateMousemove,
      rateMouseleave
    }
  }
})
</script>
